/* describes a sprite that is moving on the screen, collecting pickups */
class Collector {

	/* initialize */
	constructor(world_game) {

		/* save instance of game, to interact with it */
		this.world_game = world_game;

		/* constant states */
		this.WAITING = 0;
		this.MOVING = 1;

		/* starting state (timer is used for animations) */
		this.state = this.WAITING;
		this.timer_max = Collector.new_timer;
		this.timer = this.timer_max -1;

		/* collector's textures */
		this.texture_run_array = [];
		this.texture_stand = loader.resources["images/darek_stand.png"].texture;
		for (let i = 0; i < 8; i++) {
			let tex = loader.resources["images/darek_run_" +i +".png"].texture;
			this.texture_run_array.push(tex);
		}

		/* collector's sprite */
		this.sprite = new PIXI.Sprite( this.texture_stand );
		this.sprite.anchor = {x:0.5, y:0.5};

		/* start from either left or right side of the screen, random height */
		this.sprite.x = Math.random() *2 > 1 ?
			-this.sprite.width/2 :
			width +this.sprite.width/2;
		this.sprite.y = Math.floor( Math.random() *height );

		/* add collector to screen, based on his y value
		 * so it appears properly in front or behind objects
		 * also calculate its position inside the y sorted array
		 */
		let ground = world_game.ground_container;
		let position = ground.children.length;
		let y = this.sprite.y +this.sprite.height/2;
		for (let i = 0; i < ground.children.length; i++) {
			let y2 = ground.children[i].y +ground.children[i].height;
			if (y < y2) {
				position = i;
				break;
			}
		}
		world_game.ground_container.addChildAt(this.sprite, position);

		/* target pickup. -1 means there is no target,
		 * any other greater value is the index of target pickup
		 */
		this.target = -1;

		/* when targeting a pickup, save old location, and pickup's location,
		 * in order to animate between them
		 */
		this.old_loc = new PIXI.Point(0, 0);
		this.new_loc = new PIXI.Point(0, 0);

	} /* constructor */

	/* animate, move sprite and collect crystals */
	update() {

		/* advance animation */
		this.timer++;

		/* animation ended */
		if (this.timer >= this.timer_max) {

			/* based on what was being animated */
			switch (this.state) {

				/* collector was waiting */
				case this.WAITING:

					/* 50% it will wait for another second */
					if ( Math.random() < 0.5 ) {
						this.sprite.scale.x *= -1;
                                                this.timer -= 30;
                                        }
					/* start running towards a pickup with new speed */
                                        else {
						this.timer_max = Collector.new_timer;
						this.change_state(this.MOVING);
					}
					break;

				/* collector was moving */
				case this.MOVING:
				default:

					/* stop running and wait */
					this.change_state(this.WAITING);
					break;

			} /* switch state */

		}
		/* animation is still active */
		else {

			/* depending on what is being animated */
			switch (this.state) {

				/* collector is waiting */
				case this.WAITING:

					/* every 30 frames, there's 10% chance collector
					 * will look on a different side (like he is searching)
					 */
					if (this.timer % 30 == 0 && Math.random() < 0.1) {
						this.sprite.scale.x *= -1;
					}
					break;

				/* collector is running */
				case this.MOVING:

					/* move sprite from old location, to new location, based on timer/timer_max */
					this.sprite.x = this.old_loc.x +((this.new_loc.x -this.old_loc.x) /this.timer_max *this.timer);
					this.sprite.y = this.old_loc.y +((this.new_loc.y -this.old_loc.y) /this.timer_max *this.timer);

					/* check if collector moved behind or in front of another object */
					let ground = this.world_game.ground_container;
					let pos = ground.getChildIndex(this.sprite);
					while (pos > 0 && (this.sprite.y +this.sprite.height/2) <= (ground.children[pos-1].y +ground.children[pos-1].height/2)) {
						ground.swapChildren(this.sprite, ground.children[pos-1]);
						pos--;
					}

					while (pos < ground.children.length-1 &&
						(this.sprite.y +this.sprite.height/2) >=
						(ground.children[pos+1].y +ground.children[pos+1].height/2)) {
						ground.swapChildren(this.sprite, ground.children[pos+1]);
						pos++;
					}

					/* animate collector */
					this.sprite.texture = this.texture_run_array[ Math.floor( (this.timer /5) %8 ) ];
					break;

			} /* switch state */

		} /* animation is still running */

	} /* update end */

	/* randomly select a new pickup as target */
	find_target() {

		/* pickups alias */
		let pickups = this.world_game.spawner.array;

		/* if no pickups, no target is selected */
		if (pickups.length == 0) {
			this.target = -1;
			return;
		}

		/* pick new target from pickup array, randomly */
		this.target = Math.floor( Math.random() *pickups.length );

		/* save current location */
		this.old_loc.x = this.sprite.position.x;
		this.old_loc.y = this.sprite.position.y;

		/* save target location */
		this.new_loc.x = pickups[this.target].position.x;
		this.new_loc.y = pickups[this.target].position.y
			+pickups[this.target].height/2
			-this.sprite.height/2;

		/* face either left or right, to new target */
		this.sprite.scale.x =
			this.new_loc.x > this.old_loc.x ? 1 : -1;

	} /* end find_target */

	/* a specific pickup was collected, if it was this collector's target,
	 * stop running for it, and start waiting again
	 */
	notify_collected(i) {

		/* pickup collected was target,
		 * start waiting
		 */
		if (this.target == i) {
			this.change_state(this.WAITING);
			return;
		}

		/* target had higher index than pickup collected,
		 * since pickup array is sliced, move target one space below.
		 */
		if (this.target > i) {
			this.target--;
		}

	} /* end notify_collected */

	/* change between states */
	change_state(STATE) {

		/* depending on current state */
		switch (this.state) {

			/* previous state was waiting */
			case this.WAITING:

				/* change state, reset animation, find new target (TO FIX) */
				this.find_target();
				if (this.target == -1) {
					this.timer = 0;
				}
				else {
					this.state = STATE;
					this.timer = 0;
				}
				break;

			/* previous state was moving */
			case this.MOVING:
			default:

				/* change to new state */
				this.state = STATE;

				/* animation was finished and not interrupted */
				if (this.timer >= this.timer_max) {

					/* save target and notify game that this collector is collecting
					 * a specific pickup
					 * but first remove it from self, so it doesn't notify itself
					 */
					let target = this.target;
					this.target = -1;
					this.world_game.pickup(target); /* TO FIX */
				}

				/* reset animation */
				this.timer = 0;


				/* reset animation frame */
				this.sprite.texture = this.texture_stand;
				break;
		}

	} /* change_state */

} /* Collector */
